/* kernel.h - David Young */
#ifndef __kernel_h__
#define __kernel_h__
#define dd(x)                            \
        __asm _emit (x)       & 0xff     \
        __asm _emit     (x) >> 8  & 0xff \
        __asm _emit     (x) >> 16 & 0xff \
        __asm _emit     (x) >> 24 & 0xff

#define KERNEL_STACK               0x00103fff
#define KERNEL_START               0x00101000
#define KERNEL_LENGTH               0x0000200F

//Funcs
void kmain(unsigned long, unsigned long);

extern "C" void gdt_flush();
void gdt_install();
void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran);

//DATA STRUCTS
#pragma pack(push, 1)

struct multiboot_info {
	unsigned int flags;
	
	unsigned int low_mem;
	unsigned int high_mem;
	
	unsigned int boot_device;
	unsigned int cmd_line;
	
	unsigned int mods_count;
	unsigned int mods_addr;
	
	unsigned int syms1;
	unsigned int syms2;
	unsigned int syms3;
	unsigned int syms4;
	
	unsigned int mmap_length;
	unsigned int mmap_addr;
	
	unsigned int drives_length;
	unsigned int drives_addr;
	
	unsigned int config_table;
	unsigned int boot_loader_name;
	unsigned int apm_table;
	
	unsigned int vbe_control_info;
	unsigned int vbe_mode_info;
	unsigned short vbe_mode;
	unsigned short vbe_interface_seg;
	unsigned short vbe_interface_off;
	unsigned short vbe_interface_len;
};

struct gdt_entry
{
    unsigned short limit_low;
    unsigned short base_low;
    unsigned char base_middle;
    unsigned char access;
    unsigned char granularity;
    unsigned char base_high;
};

struct gdt_ptr
{
    unsigned short limit;
    unsigned int base;
};

struct multiboot_info * mbinfo;
struct gdt_entry gdt[3];
struct gdt_ptr gp;
#pragma pack(pop)

//////////////////////////////////////////////////////////////////////////////////////////////////////////
/////KERNEL VIDEO FUNCS///////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
#define VIDEOMEM 0xB8000
enum Color { BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LIGHT_GRAY, DARK_GRAY, LIGHT_BLUE,
			 LIGHT_GREEN, LIGHT_CYAN, LIGHT_RED, LIGHT_MAGENTA, LIGHT_BROWN, WHITE };
			 
struct video_info {
	unsigned int vmode;
	unsigned int screen_width;
	unsigned int screen_height;
	char curr_locx;
	char curr_locy;
};
struct video_info vinfo;
void kprint(int x, int y, char lett, char attrib);
void kprint(char* string);
void kclear();
void init_vid();
#endif
